﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_ProDivingAdmin2salmon14
{
    public class Contest
    {
        public static ObservableCollection<string> judgeScores;
        public static List<Judge> judgeList { get; set; }
        public int amountOfJudges { get; set; }
        public int amountOfDives { get; set; }
        public DiverList diverList { get; set; }
        public bool isDone { get; set; }
        public bool isFemale { get; set; }
        public int height { get; set; }
        public int minAge { get; set; }
        public static Dictionary<string, Tuple<float,string>> validDives { get; set; }


        public int diver { get; set; }
        public int dive { get; set; }

        public Contest(bool female, int minAge, int height, int judges)
        {
            isDone = false;
            diver = -1;
            dive = 0;
            this.isFemale = female;
            this.minAge = minAge;
            this.height = height;
            this.amountOfJudges = judges;
            if (minAge == 18)
            {
                if (this.isFemale)
                {
                    this.amountOfDives = 5;
                }
                else
                {
                    this.amountOfDives = 6;
                }
            }

            judgeScores = new ObservableCollection<string>();
            judgeScores.CollectionChanged += new NotifyCollectionChangedEventHandler(JudgeScoreChanged);
            validDives = new Dictionary<string, Tuple<float, string>>();
            FileManager.LoadDives("DivingScores_and_Names2salmon14.txt");

            this.GenerateValidDives();
           
            this.diverList = new DiverList("InternationalFemaleDiving10m.txt");
            Contest.judgeList = new List<Judge>(FileManager.LoadJudges("JudgeInfo.txt"));

            Console.WriteLine(diverList.Count);

            if (judgeList.Count > this.amountOfJudges || judgeList.Count < this.amountOfJudges)
            {
                System.Console.WriteLine("Error wrong amount of judges for contest!");
                isDone = true;
            }
            CommunicationServer.SetupServer();
        }

        public void NextDive()
        {

            diver++;

            if (diver > diverList.Count - 1)
            {
                diver = 0;
                dive++;
            }

            Console.WriteLine(diver + "," + dive);

            if (this.dive == this.amountOfDives)
            {
                System.Console.WriteLine("ERROR IDIOT!\nContest done!");
                isDone = true;
            }
            else if (diverList[diver].isDisqualified)
            {
                this.DCDiver(diverList[diver]);
            }
            else if (diverList[diver].isInjured) 
            {
                diverList[diver].diveList[dive].diveScore = 0.0f;
            }
            else
            {
                Console.WriteLine(diverList[diver].fullName + diverList[diver].diveList[dive].diveCode);
                SendDive(diverList[diver].diveList[dive].diveCode);
            }
        }

        private void DCDiver(Diver diver) 
        {
            foreach (var dive in diver.diveList) 
            {
                dive.diveScore = 0.0f;
            }
        }

        public void GenerateValidDives()
        {
            int lastChar = 0;
            if (this.height == 1)
            {
                
                foreach (var dive in FileManager.diveList)
                {
                    //System.Console.WriteLine("trav divelist");
                    lastChar = dive.Key.Count() - 1;
                    if (dive.Key[lastChar] == '1')
                    {
                        if (dive.Key[0] == '1' && dive.Key[2] >= '4')
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                        else if (dive.Key[0] > '1' && dive.Key[0] < '5' && dive.Key[2] >= '3')
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                        else if (dive.Key[0] == '5' && dive.Key[2] >= '2')
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                        else
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                    }
                }
            }
            else if (this.height == 3)
            {

                foreach (var dive in FileManager.diveList)
                {
                    lastChar = dive.Key.Count() - 1;
                    if (dive.Key[lastChar] == '3')
                    {
                        if (dive.Key[0] == '1' && dive.Key[2] >= '5')
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                        else if (dive.Key[0] > '1' && dive.Key[0] < '6' && dive.Key[2] >= '3')
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                        else
                        {
                            Contest.validDives.Add(dive.Key, dive.Value);
                        }
                    }
                }
            }
            else
            {
                foreach (var dive in FileManager.diveList)
                {
                    lastChar = dive.Key.Count() - 1;
                    if (dive.Key[lastChar] > '3' || dive.Key[lastChar] == '0')
                    {
                        Console.WriteLine("Adding dive: " + dive.Key);
                        Contest.validDives.Add(dive.Key, dive.Value);
                    }
                }
            }
        }

        private void JudgeScoreChanged(object sender, NotifyCollectionChangedEventArgs args) 
        {
            if (judgeScores.Count == this.amountOfJudges) 
            {
                foreach (var judgeScore in judgeScores) 
                {
                    string[] elements = judgeScore.Split(',');
                    System.Console.WriteLine(elements[1]);
                    if (!this.SetJudgeScore(Int32.Parse(elements[0]), float.Parse(elements[1], CultureInfo.InvariantCulture.NumberFormat))) 
                    {
                        System.Console.WriteLine("Invalid judge!");
                        judgeScores.Remove(judgeScore);
                        return;
                    }
                }
                judgeScores.Clear();
                diverList[diver].diveList[dive].CalculateScore();
            }
        }

        private bool SetJudgeScore(int ID, float score) 
        {
            foreach (var judge in judgeList) 
            {
                if (judge.ID == ID) 
                {
                    judge.point = score;
                    diverList[diver].diveList[dive].judgeScores.Add(new Tuple<string, float>(judge.nationality, judge.point));
                    return true;
                }
            }
            return false;
        }

        public void SendDive(string diveCode)
        {
            CommunicationServer.sendText = diveCode;
            CommunicationServer.SendDive();
        }

        public static string GetJudgeNameByID(int ID) 
        {
            foreach (var judge in judgeList) 
            {
                if (judge.ID == ID)
                {
                    return judge.fullName;
                }
            }
            return "NONE";
        }
    }
}
